﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using QuizzService.Database;

namespace QuizzService.Service
{
    public class QuizzService : IQuizzService
    {
        public IEnumerable<Theme> GetThemes()
        {
            return QuizzMeEntities.Get.Themes;
        }

        public Theme GetTheme(int id)
        {
            return QuizzMeEntities.Get.Themes.FirstOrDefault(t => t.themeId == id);
        }

        public IEnumerable<Difficulty> GetDifficulties()
        {
            return QuizzMeEntities.Get.Difficulties;
        }

        public void SetDifficulty(User user, Difficulty difficulty)
        {
            User u = QuizzMeEntities.Get.Users.FirstOrDefault(x => x.userId == user.userId);
            if (u == null)
                throw new Exception("This user does not exist : #" + user.userId);
            u.difficultyId = difficulty.difficultyId;
            QuizzMeEntities.Get.SaveChanges();
        }

        public Quizz GetRandomQuizz()
        {
            Theme t = QuizzMeEntities.Get.Themes.Random();
            return GetQuizz(t);
        }

        public Quizz GetQuizz(Theme theme)
        {
            return GetQuizzByThemeId(theme.themeId);
        }

        public Quizz GetQuizzByThemeId(int themeId)
        {
            return QuizzMeEntities.Get.Quizzs.Include("QuizzParts.Question").Where(q => q.themeId == themeId).Random();
        }

        public Quizz GetSpecificQuizz(int quizzId)
        {
            return QuizzMeEntities.Get.Quizzs.FirstOrDefault(q => q.quizzId == quizzId);
        }

        public int SaveResult(int userId, int quizzId, int score, int goodAnswers, int badAnswers, int skipAnswers)
        {
            var r = new Result
            {
                quizzId = quizzId,
                score = score,
                userId = userId,
                goodAnswers = goodAnswers,
                badAnswers = badAnswers,
                skipAnswers = skipAnswers
            };
            QuizzMeEntities.Get.Results.AddObject(r);

            QuizzMeEntities.Get.SaveChanges();

            QuizzMeEntities.Get.Users.First(user => user.userId == userId).score += score;
            QuizzMeEntities.Get.SaveChanges();

            return r.resultId;
        }

        public Result GetResult(int resultId)
        {
            return QuizzMeEntities.Get.Results.Include("Quizz.QuizzParts.Question").FirstOrDefault(r => r.resultId == resultId);
        }

        public IEnumerable<Result> GetResults(Quizz q)
        {
            return QuizzMeEntities.Get.Results.Where(r => r.quizzId == q.quizzId);
        }

        public IEnumerable<User> GetTopTen()
        {
            return QuizzMeEntities.Get.Users.OrderByDescending(u => u.score).Take(10);
        }

        public Rank GetRank(int userId)
        {
            var qme = QuizzMeEntities.Get;
            User u = qme.Users.FirstOrDefault(usr => usr.userId == userId);
            if (u == null)
                return null;
            var order = qme.Users.OrderByDescending(x => x.score);
            return new Rank {Position = order.Count(x => x.score > u.score) + 1, Total = order.Count()};
        }

        public User GetUser(int userId)
        {
            return QuizzMeEntities.Get.Users.FirstOrDefault(u => u.userId == userId);
        }

        public User GetUserByFbUid(string fbUid, string name = null)
        {
            var userByFbUid = QuizzMeEntities.Get.Users.Include("Difficulty").Where(u => u.fbId == fbUid).FirstOrDefault();
            if (userByFbUid == null)
            {
                Difficulty difficulty = QuizzMeEntities.Get.Difficulties.FirstOrDefault();
                userByFbUid = new User { fbId = fbUid, userName = name, score = 0, Difficulty = difficulty };
                QuizzMeEntities.Get.Users.AddObject(userByFbUid);
                QuizzMeEntities.Get.SaveChanges();
            }
            else
            {
                if (name != null)
                    userByFbUid.userName = name;
                
                QuizzMeEntities.Get.SaveChanges();
            }
            if (userByFbUid.Difficulty == null)
                Debugger.Break();
            return userByFbUid;
        }

        //public User RegisterUser(IDictionary<string, object> userId)
        //{
        //    User user = GetUserByFbUid((string) userId["id"]);
        //    if (user == null)
        //        try
        //        {
        //            user = new User
        //                       {
        //                           //TODO: fixme
        //                           Difficulty = null,
        //                           //QuizzMeEntities.Get.Difficulties.fi
        //                           fbId = (string) userId["id"],
        //                           login = (string) userId["email"],
        //                           score = 0
        //                       };
        //            var quizzMeEntities = QuizzMeEntities.Get;
        //            quizzMeEntities.Users.AddObject(user);
        //            quizzMeEntities.SaveChanges();
        //        }
        //        catch (Exception e)
        //        {
        //            Trace.TraceError(e.Message);
        //            return null;
        //        }
        //    return user;
        //}
    }
}
